package com.xjoyt.pay.master.core.order.handle.create;

import java.util.Date;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.github.wxiaoqi.security.common.util.OrderUtils;
import com.xjoyt.pay.commons.ObjectUtils;
import com.xjoyt.pay.dto.ExecuteResult;
import com.xjoyt.pay.gateway.params.OrderCreateParam;
import com.xjoyt.pay.gateway.params.OrderParam;
import com.xjoyt.pay.master.core.order.handle.AbstractOrderCreateHandle;
import com.xjoyt.pay.master.dto.OrderUrlResult;
import com.xjoyt.pay.master.po.DistributorRate;
import com.xjoyt.pay.master.po.Merchant;
import com.xjoyt.pay.master.po.MerchantChannel;
import com.xjoyt.pay.master.po.MerchantChannelRate;
import com.xjoyt.pay.master.po.Order;
import com.xjoyt.pay.master.po.OrderConfig;
import com.xjoyt.pay.master.po.PayChannel;
import com.xjoyt.pay.master.repository.OrderConfigRepository;
import com.xjoyt.pay.vo.PayType;

/**
 * 保存
 * 
 * @author Administrator
 *
 */
@Component
@Scope("prototype")
public class SaveHandle extends AbstractOrderCreateHandle {

	@Autowired
	private OrderConfigRepository orderConfigRepository;

	@Override
	public ExecuteResult<OrderUrlResult> handle(OrderParam param, PayType payType, Map<String, Object> args) {

		MerchantChannel merchantChannel = getObject(MerchantChannel.class, args);
		
		PayChannel payChannel = getObject(PayChannel.class, args);
		
		
		Merchant merchant = getObject(Merchant.class, args);
		DistributorRate distributorRate = getObject(DistributorRate.class, args);

		Double rate = null;
		Long poundage = 0L;

		Long limit = 0L, minimum = 0L;
		//TODO ?商户通道需要设置多个费率???一个商户通道对应一个汇率即可.
		if (CollectionUtils.isNotEmpty(merchantChannel.rates))
			for (MerchantChannelRate item : merchantChannel.rates) {
				if (payType.equals(item.type)) {
					rate = item.rate / 100;
					//TODO 是否使用固定费率还是应该按照费率值计算?
					poundage = item.money == null ? 0 :  item.money * 1;
					limit = item.limit == null ? 0 :  item.limit * 1;
					minimum = item.minimum == null ? 0 :  item.minimum * 1;
					break;
				}
			}

		if (rate == null)
			return ExecuteResult.fail("商户通道费率未设置");

		Order entity = new Order();
		putObject(entity, args);

//		ObjectUtils.fieldCopy(param, entity);
		entity.channelRate = payChannel.rate == null ? 0D : payChannel.rate / 100;
		entity.channelLimit = payChannel.limit == null ? 0L : payChannel.limit;
		entity.channelMinimum = payChannel.minimum == null ? 0L : payChannel.minimum;
		entity.channelPoundage = payChannel.money == null ? 0L : payChannel.money;
		entity.costLimit = distributorRate.limit == null ? 0L : distributorRate.limit;
		//代理商有可能是使用费率进行计算.
		//TODO 一个商户可能有多个代理商.代理商的费用为一个月结算一次.通过提现实现?
		entity.costPoundage = distributorRate.money == null ? 0L : distributorRate.money;
		entity.costMinimum = distributorRate.minimum == null ? 0L : distributorRate.minimum;
		entity.money = param.money == null ? 0 : param.money;
		entity.tradeType = param.type;
		entity.outTradeNo = param.outTradeNo;
		entity.authCode = param.authCode;
		entity.payMethod = param.payMethod;
		entity.addedDate = new Date();
//		entity.merchant = merchant;
		entity.merchantNo = merchant.no;
		entity.merchantName = merchant.name;
		entity.successUrl = param.successUrl;
		entity.poundage = poundage;
		entity.payType = payType;
		//TODO 校验是否超过最大值?最小值?是否真的需要判断??
		if (limit > 0 && (entity.money * rate) >= limit) {
			entity.rate = 0D;
			entity.limit = limit;
			entity.minimum = 0L;
		} else if (minimum > 0 && (entity.money * rate) <= minimum) {
			entity.rate = 0D;
			entity.minimum = minimum;
			entity.limit = 0L;
		} else {
			entity.rate = rate;
			entity.limit = 0L;
			entity.minimum = 0L;
		}
		
		
		//订单生成采用统一订单生成方式.防止重复生成订单.
		entity.no = OrderUtils.genUniOrder();
		//TODO 保存订单
		entity = repository.save(entity);
		entity.orderConfig = new OrderConfig();
		entity.orderConfig.order = entity;
		entity.orderConfig.id = entity.id;
		entity.orderConfig.notifyUrl = param.callbackUrl + entity.id;
		entity.orderConfig.successUrl = param.callbackSuccessUrl + entity.id;
		entity.orderConfig.no = merchantChannel.no;
		entity.orderConfig.key = merchantChannel.key;

		entity.orderConfig.url = payChannel.url;
		entity.orderConfig.payUrl = payChannel.payUrl;
		entity.orderConfig.checkUrl = payChannel.channel.checkUrl;
		// entity.orderConfig.backUrl = payChannel.backUrl;
		entity.orderConfig.callbackUrl = payChannel.callbackUrl;
		entity.orderConfig.channel = payChannel.channel;
		entity.orderConfig.channelName = payChannel.channel.name;
		entity.orderConfig.channelNo = payChannel.channel.no;
		entity.orderConfig.costRate = distributorRate.rate == null ? 0D : distributorRate.rate / 100;
		entity.tradeMerchantNo = merchantChannel.no;
		//保存订单配置
		entity.orderConfig = orderConfigRepository.save(entity.orderConfig);
		return getNext().handle(param, payType, args);
	}
}
